$(document).ready(function () {

    $.fn.calendar = function (options) {

        var args = $.extend({}, $.fn.calendar.defaults, options);

        this.each(function () {

            var calendar;
            var lblDaysMonth;
            var lblTextMonth = $('<div class="visualmonthyear"></div>');

            var calendar_id = "cal_" + Math.floor(Math.random() * 99999).toString(36);

            var events = args.events;

            var gsHub = $.connection.goodsHub;

            gsHub.client.setNotAvailableDays = function (noAvDays, month, year) {
                events = noAvDays;
                markEvents(month, year);
            };


            var days;
            if (typeof args.days != "undefined")
                days = args.days;
            else
                days = ["S", "M", "T", "W", "T", "F", "S"];

            var months;
            if (typeof args.months != "undefined")
                months = args.months;
            else
                months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

            var show_days;
            if (typeof args.show_days != "undefined")
                show_days = args.show_days;
            else
                show_days = true;

            var popover_options;
            if (args.popover_options != "undefined")
                popover_options = args.popover_options;
            else
                popover_options = { placement: 'top' };

            var tooltip_options;
            if (typeof args.tooltip_options != "undefined")
                tooltip_options = args.tooltip_options;
            else
                tooltip_options = { placement: 'top' };

            var req_ajax;
            if (typeof args.req_ajax != "undefined")
                req_ajax = args.req_ajax;
            else
                req_ajax = false;

            var elem = $(this);
            showCalendar();

            /*** functions ***/

            //display
            function showCalendar() {

                //days of month label
                lblDaysMonth = $('<table class="daysmonth table table">');

                list_week();

                //date calculation object
                var dateObj = new Date();
                //check for date input
                var dateText = elem.val();
                if (dateText != "") {
                    if (validateDate(dateText)) {
                        var dateTextArray = dateText.split("/");
                        //two digit years
                        if (dateTextArray[2].length == 2) {
                            if (dateTextArray[2].charAt(0) == "0") {
                                dateTextArray[2] = dateTextArray[2].substring(1);
                            }
                            dateTextArray[2] = parseInt(dateTextArray[2]);
                            if (dateTextArray[2] < 50)
                                dateTextArray[2] += 2000;
                        }
                        dateObj = new Date(dateTextArray[2], dateTextArray[1] - 1, dateTextArray[0])
                    }
                }

                //current month & year
                var month = dateObj.getMonth();
                var year = dateObj.getFullYear();
                showDaysOfMonth(month, year);


                //next/previous month controls
                var btnNextMonth = $('<td><i class="icon-arrow-right"></i></td>');
                btnNextMonth.click(function (e) {
                    e.stopPropagation();
                    e.preventDefault();
                    month = (month + 1) % 12;
                    if (month == 0)
                        year++;
                    change_month(month, year);
                });
                var btnPrevMonth = $('<td><i class="icon-arrow-left"></i></td>');
                btnPrevMonth.click(function (e) {
                    e.stopPropagation();
                    e.preventDefault();
                    month = (month - 1);
                    if (month == -1) {
                        year--;
                        month = 11;
                    }
                    change_month(month, year);
                });
                $('.icon-arrow-left').css('cursor', 'pointer');
                $('.icon-arrow-right').css('cursor', 'pointer');

                //current year & month label
                var lblDate = $('<table class="table header"><tr></tr></table>');
                var lblDateControl = $('<td colspan=5 class="year span6"></td>');
                lblDate.append(btnPrevMonth);
                lblDate.append(lblDateControl);
                lblDate.append(btnNextMonth);
                lblDateControl.append(lblTextMonth);

                calendar = $('<div class="calendar" id="' + calendar_id + '" ></div>');
                calendar.prepend(lblDate);
                //calendar.append(lblWeek);
                //lblDaysMonth.prepend(lblWeek);
                calendar.append(lblDaysMonth);

                //render calendar
                elem.append(calendar);

                check_events(month, year);
            }

            function change_month(month, year) {
                lblDaysMonth.empty();
                list_week();
                showDaysOfMonth(month, year);
                check_events(month, year);
            }

            //week
            function list_week() {
                if (show_days != false) {
                    var lblWeek = $('<tr class="week_days" >');
                    var insertCode = '';
                    $(days).each(function (key, value) {
                        insertCode += '<td';
                        if (key == 0) {
                            insertCode += ' class="first"';
                        }
                        if (key == 6) {
                            insertCode += ' class="last"';
                        }
                        insertCode += ">" + value + '</td>';
                    });
                    insertCode += '</tr>';
                    lblWeek.append(insertCode);

                    lblDaysMonth.append(lblWeek);
                }
            }

            function showDaysOfMonth(month, year) {
                //console.log("show (month, year): ", month, " ", year)
                lblTextMonth.text(months[month] + " " + year);

                //days of month
                var day_counter = 1;


                var firstDay = calculateWeekday(1, month, year);
                var lastDaymonth = lastDay(month, year);

                var next_month = month + 1;

                var lblDaysMonth_string = "";

                //render first row of week
                for (var i = 0; i < 7; i++) {
                    if (i < firstDay) {
                        var dayCode = "";
                        if (i == 0)
                            dayCode += "<tr>";
                        //if the day of the week is less than the number of the first day of the week do not put anything in the cell
                        dayCode += '<td class="invalid';
                        if (i == 0)
                            dayCode += " first";
                        dayCode += '"></td>';
                    } else {
                        var dayCode = "";
                        if (i == 0)
                            dayCode += '<tr>';
                        dayCode += '<td id="' + calendar_id + '_' + day_counter + "_" + next_month + "_" + year + '" ';
                        if (i == 0)
                            dayCode += ' class="first"';
                        if (i == 6)
                            dayCode += ' class="last"';
                        dayCode += '><a>' + day_counter + '</a></span>';
                        if (i == 6)
                            dayCode += '</tr>';
                        day_counter++;
                    }
                    lblDaysMonth_string += dayCode
                }

                //rest of month
                var currentWeekDay = 1;
                while (day_counter <= lastDaymonth) {
                    var dayCode = "";
                    if (currentWeekDay % 7 == 1)
                        dayCode += "<tr>";
                    dayCode += '<td id="' + calendar_id + '_' + day_counter + "_" + next_month + "_" + year + '" ';
                    //start of week
                    if (currentWeekDay % 7 == 1)
                        dayCode += ' class="first"';
                    //end of week
                    if (currentWeekDay % 7 == 0)
                        dayCode += ' class="last"';
                    dayCode += '><a>' + day_counter + '</a></td>';
                    if (currentWeekDay % 7 == 0)
                        dayCode += "</tr>";
                    day_counter++;
                    currentWeekDay++;
                    lblDaysMonth_string += dayCode
                }

                //fill empty days
                currentWeekDay--;
                if (currentWeekDay % 7 != 0) {
                    dayCode = "";
                    for (var i = (currentWeekDay % 7) + 1; i <= 7; i++) {
                        var dayCode = "";
                        dayCode += '<td class="invalid';
                        if (i == 7)
                            dayCode += ' last'
                        dayCode += '"></td>';
                        if (i == 7)
                            dayCode += '</tr>'
                        lblDaysMonth_string += dayCode
                    }
                }

                lblDaysMonth.append(lblDaysMonth_string);
            }
            //calcuation number of days in week
            function calculateWeekday(day, month, year) {
                var dateObj = new Date(year, month, day);
                var numDay = dateObj.getDay();
                return numDay;
            }

            //date validation
            function checkdate(m, d, y) {
                // function by http://kevin.vanzonneveld.net
                // extracted from the manual phpjs.org libraries at http://www.desarrolloweb.com/manuales/manual-librerias-phpjs.html
                return m > 0 && m < 13 && y > 0 && y < 32768 && d > 0 && d <= (new Date(y, m, 0)).getDate();
            }

            //calculate last day of month for a given year
            function lastDay(month, year) {
                var last_day = 28;
                while (checkdate(month + 1, last_day + 1, year)) {
                    last_day++;
                }
                return last_day;
            }

            function validateDate(date) {
                var dateArray = date.split("/");
                if (dateArray.length != 3)
                    return false;
                return checkdate(dateArray[1], dateArray[0], dateArray[2]);
            }

            function check_events(month, year) {
                $.connection.hub.start().done(function () {
                    gsHub.server.getNotAvailableDays(goodId, month, year);
                });
                //markEvents(month, year);
            }

            function markEvents(month, year) {
                var t_month = month + 1;

                for (var i = 0; i < events.length; i++) {

                    if (events[i][0].split('/')[1] == t_month && events[i][0].split('/')[2] == year) {

                        $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_")).addClass('event');

                        $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a').attr('data-original-title', events[i][1]);

                        //bg
                        if (events[i][3])
                            $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_")).css('background', events[i][3]);

                        //link
                        if (events[i][2] == '' || events[i][2] == '#') {
                            if (events[i][4] != '') {
                                $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a').attr('data-trigger', 'manual');
                                $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a').addClass('manual_popover');
                            } else {
                                $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a').attr('href', 'javascript:false;');
                            }
                        } else {
                            $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a').attr('href', events[i][2]);
                        }


                        //tooltip vs popover
                        if (events[i][4]) {
                            $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_")).addClass('event_popover');
                            $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a').attr('rel', 'popover');
                            $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a').attr('data-content', events[i][4]);
                        } else {
                            $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_")).addClass('event_tooltip');
                            $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a').attr('rel', 'tooltip');
                        }
                    }
                }

                //$('#' + calendar_id + ' ' + '.event_tooltip a').tooltip(tooltip_options);
                //$('#' + calendar_id + ' ' + '.event_popover a').popover(popover_options);

                //$('.manual_popover').click( function(){
                //    $(this).popover('toggle');
                //} );
            }

            /*** --functions-- ***/

        });
        return this;
    };


    theMonths = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
    theDays = ["S", "M", "T", "W", "T", "F", "S"];
    $('.calendar_test').calendar({
        months: theMonths,
        days: theDays,
        events: events
    });
});